package com.sz.sidi.oa.katable;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;

import util.Assert;

import com.sz.sidi.util.TimeHelper;


import de.kupzog.ktable.SWTX;
import de.kupzog.ktable.KTableCellEditor;
import de.kupzog.ktable.KTableCellRenderer;
import de.kupzog.ktable.KTableSortedModel;
import de.kupzog.ktable.editors.KTableCellEditorCheckbox2;
import de.kupzog.ktable.renderers.CheckableCellRenderer;
import de.kupzog.ktable.renderers.FixedCellRenderer;
import de.kupzog.ktable.renderers.TextCellRenderer;

public class ShowKTableModel extends KTableSortedModel {
	
	// 表格设置默认值
	public static int Table_Height = 25;// 行高
	public static Font Table_FONT = DoctorConfiguration.f10;// 字体大小 9-12
	
	public static Color Table_Background = new Color(Display.getDefault(), new RGB(255,
			255, 0));// 表格背景色
	public static Color Table_color = new Color(Display.getDefault(), new RGB(0,
			0, 0));// 表格字体颜色

	public static Color Table_Groupcolor = new Color(Display.getDefault(), new RGB(0,
			0, 0));// 同组字体颜色
	
	public static Color Table_GroupBackground = new Color(Display.getDefault(), new RGB(240,243,248));

	private Font HeaderFont = DoctorConfiguration.f10;

	static Color red = new Color(Display.getDefault(), new RGB(0, 0,
			0));
	
	private Color BGROWFOCUS = new Color(Display.getDefault(), new RGB(255, 140,
			0));
	
	private Color Foreground = new Color(Display.getDefault(), new RGB(255,
			0, 0));// 同组字体颜色
	private Color backgroundColor = Table_Background;
	private Color rowBackgroundColor = Table_GroupBackground;
	private Color rowColor = Table_Groupcolor;
	private int rowHeight = 25;
	
	protected String[] columnTitles;
	String[] columnProperties;
	private boolean haveCheckbox = false;// 第一列为Checkbox

	private int rowCount;
	private int columnCount;

	protected int fixRowCount;
	private int fixColumnCount;

	private int[] columnWidths;

	private int[] columnAligns;

	protected Map<String, Object> contentMap = new Hashtable<String, Object>();

	private Map<Integer, Object> rowMap = new Hashtable<Integer, Object>();
	protected LKCellStyleProvider cellStyleProvider = null;

	private FixedCellRenderer m_FixedRenderer = new FixedCellRenderer(
			FixedCellRenderer.STYLE_FLAT | FixedCellRenderer.INDICATION_SORT
					| FixedCellRenderer.INDICATION_FOCUS
					| FixedCellRenderer.INDICATION_CLICKED);

	private final TextCellRenderer m_textRenderer = new TextCellRenderer(
			TextCellRenderer.INDICATION_FOCUS_ROW);

	private KTableCellRenderer m_CheckableRenderer = new CheckableCellRenderer(
			CheckableCellRenderer.INDICATION_CLICKED
					| CheckableCellRenderer.INDICATION_FOCUS);
	public List<Object> oldDataList;
	private String checkboxPropertie;//复选按钮的列对应数据库字段
	protected String datePatten = "MM-dd HH:mm";//日期格式
	protected static final NumberFormat numberFormater = NumberFormat
			.getNumberInstance();
	
	//Added by CYX 2010.01.04 ,改变显示的值,与LabelProvider类似
	protected ISKJoinOutValue joinOut = null;

	/*
	 * dataList数据
	 * columnTitles列名
	 * columnProperties列对应数据库字段
	 * columnWidths列宽
	 * fixRowCount行固定列数
	 * fixColumnCount列固定列数
	 * haveCheckbox是否有勾选的复选按钮
	 * checkboxPropertie复选按钮的列对应数据库字段
	 * datePatten日期格式
	 */
	public ShowKTableModel(List<Object> dataList, String[] columnTitles,
			String[] columnProperties, int[] columnWidths, int fixRowCount,
			int fixColumnCount,String datePatten, boolean haveCheckbox,String checkboxPropertie) {
		this.haveCheckbox = haveCheckbox;
		this.checkboxPropertie = checkboxPropertie;
		this.columnProperties = columnProperties;
		this.datePatten = datePatten;
		init(dataList, columnTitles, columnProperties, columnWidths, 
				fixRowCount, fixColumnCount);
	}

	/*
	 * dataList数据
	 * columnTitles列名
	 * columnProperties列对应数据库字段
	 * columnWidths列宽
	 * fixRowCount行固定列数
	 * fixColumnCount列固定列数
	 * datePatten日期格式
	 */
	public ShowKTableModel(List<Object> dataList, String[] columnTitles,
			String[] columnProperties, int[] columnWidths, int fixRowCount,
			int fixColumnCount,String datePatten) {
		this.datePatten = datePatten;
		init(dataList, columnTitles, columnProperties, columnWidths, 
				fixRowCount, fixColumnCount);
	}
	
	public List<Object> getData() {
		List<Object> dataList = new ArrayList<Object>();
		dataList.addAll(oldDataList);
		for (int i = getFixedHeaderRowCount(); i < this.rowCount; i++) {
			Object obj = dataList.get(i);
			for (int j = 0; j < columnCount; j++) {
				String fieldName = columnProperties[j];
				if(fieldName!=null&&!fieldName.trim().equals("")){
					Object fieldValue = contentMap.get(j + "," + i);
					DoctorConfiguration.setProperty(obj, fieldName, fieldValue);
				}
			}
			dataList.set(i, obj);
		}
		return dataList;
	}

	public Object getRow(int row) {
		return rowMap.get(mapRowIndexToModel(row) - 1);
	}

	public void setData(List<Object> dataList) {
		if (dataList != null) {
			rowCount = dataList.size();
			oldDataList = dataList;
		} else {
			oldDataList = new ArrayList();
			rowCount = 0;
		}

		rowMap.clear();
		contentMap.clear();

		for (int i = 0; i < rowCount; i++) {
			Object obj = dataList.get(i);
			rowMap.put(i, obj);
			for (int j = 0; j < columnCount; j++) {
				String fieldName = columnProperties[j];
				//Modified by CYX
//				Object value = DoctorConfiguration.getProperty(obj, fieldName);
				Object value = getProperty(obj, fieldName);
				if (value == null)
					value = "";
				contentMap.put(j + "," + i, value);
			}
		}
	}
	/**
	 * Added by CYX 
	 * 读取嵌套属性的值
	 * @param obj
	 * @param fieldName
	 * @return
	 */
	private Object getProperty(Object obj ,String fieldName){
		if(obj == null || fieldName == null){
			return null;
		}
		Object tempObj = obj;
		Object value = null;
		String[] fieldList = fieldName.split("\\.");
		for(int index = 0; index < fieldList.length;index++){
			if(tempObj == null){
				break;
			}
			value = DoctorConfiguration.getProperty(tempObj, fieldList[index]);
			tempObj = value;
			
		}
		return value;
	}

	private void init(List<Object> dataList, String[] columnTitles,
			String[] columnProperties, int[] columnWidths,
			int fixRowCount, int fixColumnCount) {
		numberFormater.setMaximumFractionDigits(2);
		numberFormater.setGroupingUsed(false);
		this.columnProperties = columnProperties;
		this.columnTitles = columnTitles;
		if (columnProperties != null) {
			columnCount = columnProperties.length;
		} else {
			columnCount = 0;
		}

		this.columnWidths = columnWidths;

		this.fixRowCount = fixRowCount;
		this.fixColumnCount = fixColumnCount;

		m_FixedRenderer.setAlignment(SWTX.ALIGN_HORIZONTAL_CENTER
				| SWTX.ALIGN_VERTICAL_CENTER|SWTX.WRAP);

		m_FixedRenderer.setFont(HeaderFont);
		
		m_textRenderer.setFont(Table_FONT);

		m_textRenderer.COLOR_BGROWFOCUS = BGROWFOCUS;

		FixedCellRenderer.COLOR_LINE_LIGHTGRAY = new Color(
				Display.getDefault(), new RGB(0xC2, 0xC2, 0xC2));

		setData(dataList);
		initialize();
	}

	@Override
	public Point doBelongsToCell(int col, int row) {
		return new Point(col, row);
	}

	@Override
	public KTableCellEditor doGetCellEditor(int col, int row) {
//		if (haveCheckbox && columnProperties[col].equals(checkboxPropertie)&& row >= getFixedHeaderRowCount()) {
//			Rectangle imgBounds = CheckableCellRenderer.IMAGE_CHECKED
//					.getBounds();
//			Point sensible = new Point(imgBounds.width, imgBounds.height);
//			return new KTableCellEditorCheckbox2(sensible,
//					SWTX.ALIGN_HORIZONTAL_CENTER, SWTX.ALIGN_VERTICAL_TOP);
//		}
		return null;
	}

	@Override
	public KTableCellRenderer doGetCellRenderer(int col, int row) {
		if (haveCheckbox && columnProperties[col].equals(checkboxPropertie)&& row >= getFixedHeaderRowCount()) {
			return m_CheckableRenderer;
		}
		if (isHeaderCell(col, row)) {
			// 表头
			m_FixedRenderer.setFont(HeaderFont);
			return m_FixedRenderer;
		}
		
		if (this.columnAligns != null) {
			TextCellRenderer renderer = new TextCellRenderer(
					TextCellRenderer.INDICATION_FOCUS_ROW);
				renderer.setAlignment(columnAligns[col]
						| SWTX.ALIGN_VERTICAL_TOP|SWTX.WRAP);

			renderer.setFont(Table_FONT);
			renderer.setForeground(Foreground);
			renderer.setBackground(backgroundColor);

			if (row % 2 == 0) {
				renderer.setBackground(rowBackgroundColor);
				renderer.setForeground(rowColor);
			}
			if (cellStyleProvider != null) {
				Color back = null;
				Color forge = null;
				Object t = oldDataList.get(row - getFixedHeaderRowCount());

				back = cellStyleProvider
						.getBackground(t, columnProperties[col]);
				forge = cellStyleProvider.getForeground(t,
						columnProperties[col]);

				if (back != null)
					renderer.setBackground(back);
				if (forge != null)
					renderer.setForeground(forge);
			}

			return renderer;
		}

		// m_textRenderer.setForeground(Foreground);
		m_textRenderer.setFont(Table_FONT);
		return m_textRenderer;
	}

	public Object getContent(int col, int row) {
		if (col == 0 && row == 0) {
			return "";
		}
		if (col < 1) {
			return row;
		}
		if (row < getFixedHeaderRowCount()) {
			return this.columnTitles[col];
		}
		String key = (col) + ","
				+ (row - this.fixRowCount);
		Object value = this.contentMap.get(key);

		if (haveCheckbox && columnProperties[col].equals(checkboxPropertie)
				&& row >= getFixedHeaderRowCount()) {
			return value;
		}

		if (value == null)
			value = "";

		return value;
	}

	@Override
	public Object doGetContentAt(int col, int row) {

		if (col == 0 && row == 0) {
			return "";
		}
		if (col < 1) {
			return row;
		}
		//TODO 这里会造成所有的固定行都显示表头
		if (row < getFixedHeaderRowCount()) {
			return this.columnTitles[col];
		}
		String key = (col) + ","
				+ (row - this.fixRowCount);
		Object value = this.contentMap.get(key);

		if (haveCheckbox && columnProperties[col].equals(checkboxPropertie)
				&& row >= getFixedHeaderRowCount()) {
			return value;
		}
		if (value == null)
			value = "";

		if (value instanceof Double) {
			value = numberFormater.format(((Double) value));
			try {
				value = numberFormater.parse(value.toString()).doubleValue();
			} catch (ParseException e) {
				e.printStackTrace();
			}
		} else if (value instanceof BigDecimal) {
			value = numberFormater.format(((BigDecimal) value));
			try {
				value = numberFormater.parse(value.toString()).doubleValue();
			} catch (ParseException e) {
				e.printStackTrace();
			}
		} else if (value instanceof Float) {
			value = numberFormater.format(((Float) value));
			try {
				value = numberFormater.parse(value.toString()).floatValue();
			} catch (ParseException e) {
				e.printStackTrace();
			}
		} else if (value instanceof Integer) {
			value = numberFormater.format(((Integer) value));
			try {
				value = numberFormater.parse(value.toString()).intValue();
			} catch (ParseException e) {
				e.printStackTrace();
			}
		} else if (value instanceof Boolean) {
			value = ((Boolean) value != null && (Boolean) value) ? "√" : "";
		} else if (value instanceof Date) {
			value = TimeHelper.dateToString((Date) value, datePatten);
		}
		//Added by CYX
		if(!Assert.isNull(this.joinOut)){
			value = joinOut.getFieldValue(getRow(row),columnProperties[col], value);
		}

		return value;
	}

	@Override
	public void doSetContentAt(int col, int row, Object value) {
		String key = (col) + ","
				+ (row - this.fixRowCount);
		if (haveCheckbox && columnProperties[col].equals(checkboxPropertie)
				&& row >= getFixedHeaderRowCount()) {
			Object obj = oldDataList.get(row - this.fixRowCount);
			if(obj!=null){
				String fieldName = columnProperties[col];
				DoctorConfiguration.setProperty(obj, fieldName, value);
			}
		}
		this.contentMap.put(key, value);
	}

	public int doGetRowCount() {
		return rowCount + fixRowCount;
	}

	public int doGetColumnCount() {
		return columnCount;
	}

	public int getFixedHeaderRowCount() {
		return this.fixRowCount;
	}

	public int getFixedHeaderColumnCount() {
		return this.fixColumnCount;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see de.kupzog.ktable.KTableModel#getFixedSelectableRowCount()
	 */
	public int getFixedSelectableRowCount() {
		return 0;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see de.kupzog.ktable.KTableModel#getFixedSelectableColumnCount()
	 */
	public int getFixedSelectableColumnCount() {
		return 0;
	}

	public boolean isColumnResizable(int col) {
		return true;
	}

	public int getInitialFirstRowHeight() {
		return 25;
	}

	public boolean isRowResizable(int row) {
		return true;
	}

	public int getRowHeightMinimum() {
		return 20;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see de.kupzog.ktable.KTableDefaultModel#getInitialColumnWidth(int)
	 */
	public int getInitialColumnWidth(int column) {
		return this.columnWidths[column];
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see de.kupzog.ktable.KTableDefaultModel#getInitialRowHeight()
	 */
	public int getInitialRowHeight(int row) {
		if(row<getFixedHeaderRowCount()){
			return 25;
		}
		return this.rowHeight;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see de.kupzog.ktable.KTableDefaultModel#doGetTooltipAt(int, int)
	 */
	public String doGetTooltipAt(int col, int row) {
		return "";
	}

	public void setColumnAligns(int[] aligns) {
		this.columnAligns = aligns;
	}

	public void setColumnWidths(int[] columnWidths) {
		this.columnWidths = columnWidths;
	}

	public void setRowHeight(int rowHeight) {
		this.rowHeight = rowHeight;
	}

	public void setFixRowCount(int fixRowCount) {
		this.fixRowCount = fixRowCount;
	}

	public void setFixColumnCount(int fixColumnCount) {
		this.fixColumnCount = fixColumnCount;
	}
	
	/**
	 * added by CYX
	 * 设置joinout
	 */
	public void setJoinOut(ISKJoinOutValue joinOut){
		this.joinOut = joinOut;
	}
	public void setCellStyleProvider(LKCellStyleProvider cellStyleProvider) {
		this.cellStyleProvider = cellStyleProvider;
	}

	public void setM_FixedRenderer(FixedCellRenderer m_FixedRenderer) {
		this.m_FixedRenderer = m_FixedRenderer;
	}
}
